/*
 * UMediaPacket.cpp
 *
 *  Created on: 2020年3月26日
 *      Author: chuanjiang.zh
 */

#include "UMediaPacket.h"
#include "Ffmpeg.h"



UMediaPacket::UMediaPacket():
		m_avpkt()
{
	m_avpkt = new AVPacket();
	av_init_packet(m_avpkt);
}

UMediaPacket::~UMediaPacket()
{
	cleanup();
}

UMediaPacket::UMediaPacket(const UMediaPacket& obj):
		m_avpkt()
{
	m_avpkt = new AVPacket();
	av_init_packet(m_avpkt);

	av_packet_ref(m_avpkt, obj.m_avpkt);
	//av_packet_copy_props(m_avpkt, obj.m_avpkt);
}

UMediaPacket& UMediaPacket::operator = (const UMediaPacket& obj)
{
	av_packet_unref(m_avpkt);

	av_packet_ref(m_avpkt, obj.m_avpkt);
	//av_packet_copy_props(m_avpkt, obj.m_avpkt);

	return *this;
}

void UMediaPacket::reset()
{
	av_packet_unref(m_avpkt);

	av_init_packet(m_avpkt);
}

UMediaPacket UMediaPacket::clone()
{
	UMediaPacket pkt;
	pkt.clone(m_avpkt);
	return pkt;
}

UMediaPacket& UMediaPacket::clone(const UMediaPacket& obj)
{
	av_packet_unref(m_avpkt);

	av_packet_ref(m_avpkt, obj.m_avpkt);
	//av_packet_copy_props(m_avpkt, obj.m_avpkt);

	return *this;
}

AVPacket* UMediaPacket::get()
{
	return m_avpkt;
}

const AVPacket* UMediaPacket::get() const
{
    return m_avpkt;
}

UMediaPacket::UMediaPacket(AVPacket* avpkt) :
	m_avpkt()
{
	m_avpkt = new AVPacket();
	av_init_packet(m_avpkt);

	av_packet_ref(m_avpkt, avpkt);
}

UMediaPacket& UMediaPacket::operator = (AVPacket* avpkt)
{
	return clone(avpkt);
}

UMediaPacket& UMediaPacket::ref(AVPacket* avpkt)
{
	av_packet_unref(m_avpkt);

	if (avpkt)
	{
		av_packet_ref(m_avpkt, avpkt);
	}
	return *this;
}

UMediaPacket& UMediaPacket::clone(AVPacket* avpkt)
{
	av_packet_unref(m_avpkt);

	if (avpkt)
	{
		av_packet_ref(m_avpkt, avpkt);
		//av_packet_copy_props(m_avpkt, avpkt);
	}
	return *this;
}




void UMediaPacket::cleanup()
{
	if (m_avpkt)
	{
		av_packet_unref(m_avpkt);

		delete m_avpkt;
		m_avpkt = NULL;
	}
}

uint8_t * UMediaPacket::data()
{
	return m_avpkt->data;
}

int UMediaPacket::size() const
{
	return m_avpkt->size;
}

uint8_t * UMediaPacket::data() const
{
	return m_avpkt->data;
}

int64_t UMediaPacket::pts() const
{
	return m_avpkt->pts;
}

int64_t UMediaPacket::dts() const
{
	return m_avpkt->dts;
}

int UMediaPacket::stream_index() const
{
	return m_avpkt->stream_index;
}

int UMediaPacket::flags() const
{
	return m_avpkt->flags;
}

int UMediaPacket::duration() const
{
	return m_avpkt->duration;
}

int64_t UMediaPacket::pos() const
{
	return m_avpkt->pos;
}


void UMediaPacket::set_pts(int64_t val)
{
	m_avpkt->pts = val;
}

void UMediaPacket::set_dts(int64_t val)
{
	m_avpkt->dts = val;
}

void UMediaPacket::set_stream_index(int val)
{
	m_avpkt->stream_index = val;
}

void UMediaPacket::set_flags(int val)
{
	m_avpkt->flags = val;
}

void UMediaPacket::set_duration(int val)
{
	m_avpkt->duration = val;
}

void UMediaPacket::set_pos(int64_t val)
{
	m_avpkt->pos = val;
}

void UMediaPacket::setData(uint8_t* data, int size)
{
	m_avpkt->data = data;
	m_avpkt->size = size;
}

int UMediaPacket::copy(const AVPacket *src)
{
	return av_packet_ref(m_avpkt, src);
}

void UMediaPacket::copy(const uint8_t* data, int size)
{
	if (m_avpkt->data == nullptr)
	{
		newPacket(size);
	}

	memcpy(m_avpkt->data, data, size);
	m_avpkt->size = size;
}

int UMediaPacket::grow(int grow_by)
{
	return av_grow_packet(m_avpkt, grow_by);
}

void UMediaPacket::shrink(int size)
{
	av_shrink_packet(m_avpkt, size);
}

int UMediaPacket::newPacket(int size)
{
	int ret = av_new_packet(m_avpkt, size);
	if (ret == 0)
	{
		m_avpkt->size = size;
	}
	return ret;
}

void UMediaPacket::freePacket()
{
	av_packet_unref(m_avpkt);
}

int UMediaPacket::type() const
{
	return m_avpkt->stream_index;
}

void UMediaPacket::set_type(int val)
{
	m_avpkt->stream_index = val;
}

bool UMediaPacket::isVideo() const
{
	return (m_avpkt->stream_index == UMEDIA_TYPE_VIDEO);
}

bool UMediaPacket::isAudio() const
{
	return (m_avpkt->stream_index == UMEDIA_TYPE_AUDIO);
}

bool UMediaPacket::isAV() const
{
    return isVideo() || isAudio();
}

bool UMediaPacket::isKey() const
{
    return (flags() & AV_PKT_FLAG_KEY) != 0;
}

bool UMediaPacket::isVideoKey() const
{
    return isVideo() && isKey();
}

bool UMediaPacket::isEmpty() const
{
    return size() == 0;
}

int UMediaPacket::refTo(AVPacket* dst)
{
	int rc = av_packet_ref(dst, m_avpkt);
	return rc;
}

int UMediaPacket::assignTo(AVPacket* dst)
{
	dst->data = this->data();
	dst->size = this->size();

	dst->pts = this->pts();
	dst->dts = this->dts();
	dst->pos = this->pos();
	dst->duration = this->duration();
	dst->flags = this->flags();
	dst->stream_index = this->stream_index();

	return 0;
	//int rc = av_packet_copy_props(dst, m_avpkt);
	//return rc;
}

int UMediaPacket::copy_props(const AVPacket* src)
{
    int rc = av_packet_copy_props(m_avpkt, src);
    return rc;
}

int UMediaPacket::copy_props(const UMediaPacket& src)
{
    return copy_props(src.get());
}

void UMediaPacket::set_size(int size)
{
	m_avpkt->size = size;
}